package com.example.base.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.security.Permission;


/**
 * @ autor huangxing7
 * @ date 2018/9/3
 * @ company 杭州海康威视数字技术股份有限公司
 * @ describe 反射工具类
 */
public class ReflectUtils<P> {

    private static final String TAG = "ReflectUtils";

    public static final String FIND_ACTIVITY = "android.support.v7.app.AppCompatActivity";

    public static final String FIND_FRAGMENT = "android.support.v4.app.Fragment";


    /**
     * 获取泛型实例
     *
     * @param cls
     * @return
     */
    public static Object getGenericInstance(Class cls) {
        String genericName = getGenericName(cls);
        LogUtil.e(genericName);
        Object obj = null;
        try {
            Class<?> aClass = Class.forName(genericName);
            obj = aClass.newInstance();
        } catch (Exception e) {
            LogUtil.e(e.getMessage());
        }
        return obj;
    }

    /**
     * 获取泛型类名
     *
     * @param cls
     * @return
     */
    //((Class)((ParameterizedType)cls.getGenericSuperclass()).getActualTypeArguments()[0]).getName()
    public static String getGenericName(Class cls) {
        String genericName = "";
        try {
            Type type = cls.getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                Class clazz = (Class) ((ParameterizedType) type).getActualTypeArguments()[0];
                genericName = clazz.getName();
            } else {
                genericName = cycleClass(cls);
            }

        } catch (Exception e) {
            genericName = cycleClass(cls);
        }
        return genericName;
    }

    /**
     * 循环父类泛型
     *
     * @param cls
     * @return
     */
    public static String cycleClass(Class cls) {
        String genericName = null;
        if (cls != null && (!FIND_ACTIVITY.equals(cls.getName()) || !FIND_FRAGMENT.equals(cls.getName()))) {
            Class baseGeneric = getBaseGeneric(cls);
            genericName = getGenericName(baseGeneric);
        }
        return genericName;
    }

    /**
     * 获取父类泛型
     *
     * @param cls
     * @return
     */
    public static Class getBaseGeneric(Class cls) {
        Class baseClass = null;
        try {
            Type type = cls.getGenericSuperclass();
            if (type instanceof Class) {
                baseClass = (Class) type;
            }
        } catch (Exception e) {

        }
        return baseClass;
    }

    /**
     * 获取obj对象方法
     *
     * @param cls
     * @param methodName
     * @return
     */
    public static Method getObjMethod(Class cls, String methodName) {
        Method result = null;

        try {
            result = cls.getMethod(methodName);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 获取对象字段
     *
     * @param obj
     * @param feildName
     * @param <T>
     * @return
     */
    public static <T> T getObjFeild(Object obj, String feildName) {
        T result = null;

        Class objClass = getObjClass(obj);
        try {
            Field field = objClass.getField(feildName);
            field.setAccessible(true);
            result = (T) field.get(obj);
        } catch (Exception e) {
            LogUtil.e("getObjFeild" + e.getMessage());
        }
        return result;
    }

    public static Class getObjClass(Object obj) {
        return obj.getClass();
    }
}
